package com.inkegz.message.repo.base

import kotlinx.coroutines.*

interface Action<T, E: State<T>>{
    suspend fun opt(state: E): E
}

abstract class Reducer<T, E: State<T>> {

    var version: Long = 0

    abstract var state: E

    @Synchronized
    fun reduceAsync(action: Action<T, E>) = GlobalScope.async {
            val nState = withContext(Dispatchers.IO){ action.opt(state) }
            if (nState != state) {
                state = nState
                state.version = ++version
            }
            state
        }
}

interface State<T> {
    val model: T

    var version: Long
}
